package com.kun.service.service;

import com.kun.constants.CacheConstants;
import com.kun.domain.SysUser;
import com.kun.exception.ServiceException;
import com.kun.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 登录密码方法
 */
@Component
public class SysPasswordService {

    private final RedisService redisService;

    @Value(value = "${user.password.maxRetryCount}")
    private int maxRetryCount;

    @Value(value = "${user.password.lockTime}")
    private int lockTime;

    public SysPasswordService(RedisService redisService) {
        this.redisService = redisService;
    }

    /**
     * 登录账户密码错误次数缓存键名
     */
    private String getCacheKey(String username) {
        return CacheConstants.PWD_ERR_CNT_KEY + username;
    }

    public void validate(SysUser user) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        // 获取密码
        String password = authentication.getCredentials().toString();

        // 获取登录用户名错误次数
        int retryCount = Optional.ofNullable(redisService.getCacheObject(getCacheKey(username)))
                .map(Integer::valueOf).orElse(0);

        if (retryCount >= maxRetryCount) {
            throw new ServiceException("密码输入错误" + maxRetryCount + "次，帐户锁定" + lockTime + "分钟", HttpStatus.LOCKED);
        }

        if (!SecurityUtils.matchesPassword(password, user.getPassword())) {
            retryCount = retryCount + 1;
            redisService.setCacheString(getCacheKey(username), String.valueOf(retryCount), lockTime, TimeUnit.MINUTES);
            throw new ServiceException("密码错误", HttpStatus.UNAUTHORIZED);
        } else {
            clearLoginRecordCache(username);
        }
    }

    /**
     * 清空登录用户缓存
     */
    public void clearLoginRecordCache(String loginName) {
        if (redisService.hasKey(getCacheKey(loginName))) {
            redisService.deleteObject(getCacheKey(loginName));
        }
    }
}
